package com.kexio.user.service.impl;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.kexio.auth.cache.SimpleCacheKeyUtil;
import com.kexio.user.entity.SysDictData;
import com.kexio.user.entity.SysDictType;
import com.kexio.user.mapper.DictDataMapper;
import com.kexio.user.mapper.DictTypeMapper;
import com.kexio.user.service.DictService;

@Service
public class DictServiceImpl implements DictService {

    @Autowired
    private DictTypeMapper dictTypeMapper;
    @Autowired
    private DictDataMapper dictDataMapper;
    @Autowired
    private SimpleCacheKeyUtil simpleCacheKeyUtil;

    @Override
    public List<SysDictType> listTypes() {
        LambdaQueryWrapper<SysDictType> qw = new LambdaQueryWrapper<>();
        qw.eq(SysDictType::getDeleted, 0)
          .orderByAsc(SysDictType::getDictType);
        return dictTypeMapper.selectList(qw);
    }

    @Override
    @Cacheable(cacheNames = "dict:items", key = "@simpleCacheKeyUtil.dictKey(#typeCode)")
    public List<SysDictData> listItems(String typeCode) {
        LambdaQueryWrapper<SysDictData> qw = new LambdaQueryWrapper<>();
        qw.eq(SysDictData::getDictType, typeCode)
          .eq(SysDictData::getStatus, 1)
          .eq(SysDictData::getDeleted, 0)
          .orderByAsc(SysDictData::getDictSort);
        return dictDataMapper.selectList(qw);
    }

    @Override
    @Cacheable(cacheNames = "dict:batch", key = "@simpleCacheKeyUtil.dictKey(T(java.lang.String).join(',', #typeCodes))")
    public Map<String, List<SysDictData>> listByTypes(Collection<String> typeCodes) {
        if (typeCodes == null || typeCodes.isEmpty()) return Map.of();
        LambdaQueryWrapper<SysDictData> qw = new LambdaQueryWrapper<>();
        qw.in(SysDictData::getDictType, typeCodes)
          .eq(SysDictData::getStatus, 1)
          .eq(SysDictData::getDeleted, 0);
        return dictDataMapper.selectList(qw).stream()
            .collect(Collectors.groupingBy(SysDictData::getDictType));
    }

    @Override
    @Cacheable(cacheNames = "dict:label", key = "@simpleCacheKeyUtil.dictKey(#typeCode + ':' + #value)")
    public String getLabel(String typeCode, String value) {
        LambdaQueryWrapper<SysDictData> qw = new LambdaQueryWrapper<>();
        qw.eq(SysDictData::getDictType, typeCode)
          .eq(SysDictData::getDictValue, value)
          .last("LIMIT 1");
        SysDictData row = dictDataMapper.selectOne(qw);
        return row == null ? null : row.getDictLabel();
    }

    @Override
    @Transactional
    @CacheEvict(cacheNames = {"dict:items", "dict:label", "dict:batch"}, allEntries = true)
    public boolean createType(SysDictType type) {
        return dictTypeMapper.insert(type) > 0;
    }

    @Override
    @Transactional
    @CacheEvict(cacheNames = {"dict:items", "dict:label", "dict:batch"}, allEntries = true)
    public boolean updateType(SysDictType type) {
        return dictTypeMapper.updateById(type) > 0;
    }

    @Override
    @Transactional
    @CacheEvict(cacheNames = {"dict:items", "dict:label", "dict:batch"}, allEntries = true)
    public boolean deleteType(String id) {
        return dictTypeMapper.deleteById(id) > 0;
    }

    @Override
    @Transactional
    @CacheEvict(cacheNames = {"dict:items", "dict:label", "dict:batch"}, allEntries = true)
    public boolean createItem(SysDictData item) {
        return dictDataMapper.insert(item) > 0;
    }

    @Override
    @Transactional
    @CacheEvict(cacheNames = {"dict:items", "dict:label", "dict:batch"}, allEntries = true)
    public boolean updateItem(SysDictData item) {
        return dictDataMapper.updateById(item) > 0;
    }

    @Override
    @Transactional
    @CacheEvict(cacheNames = {"dict:items", "dict:label", "dict:batch"}, allEntries = true)
    public boolean deleteItem(String id) {
        return dictDataMapper.deleteById(id) > 0;
    }
}


